
import json
import random
import time

import redis
import requests
from flask import Blueprint, redirect,views, url_for  # 导入 Flask 中的蓝图 Blueprint 模块
from app import db


user = Blueprint("user", __name__)  # 实例化一个蓝图(Blueprint)对象
from flask import request,jsonify
from tools import Tools,My_mysql
mytool=Tools()
r=redis.Redis('localhost',6379)

class Gitee_Login(views.View):
    methods = ['GET']
    def dispatch_request(self):
        code=request.args.get('code',None)
        data={
            'grant_type':'authorization_code',
            'code':code,
            'client_id':'0a703af338f10cb37bee6a14d0fdb0f1faf4d693ff19c216900e0613210131a5',
            'redirect_uri':'http://127.0.0.1:5000/gitee',
            'client_secret':'d7c2323b4a058f33c4f186de398b7ff56ecf7a2f37d9a925bdfd020387bb74a3',
        }
        # 获取登录后的access_token
        res=requests.post(url='https://gitee.com/oauth/token',data=data)
        token=res.json()['access_token']
        # 获取用户数据
        ret=requests.get('https://gitee.com/api/v5/user?access_token='+token)
        name = ret.json()['name']
        print(name)
        # 判断是登录过
        with My_mysql(db='md2') as c:
            c.execute("select * from user where username='%s'" % name)
            user_ret = mytool.dictfetch(c)[0]
        # # 如果曾经登录过
        if user_ret:
            gitee_id=user_ret['username']
            user_id= user_ret['id']
            user_type = user_ret['type']
        else:
            # 新创建用户
            sql="INSERT INTO USER VALUES (NULL,NULL,'%s','%s','%s',NULL,NULL,NULL,NULL,NULL,NULL,NULL)"%(ret.json()['name'],mytool.md5_str(ret.json()['name']),ret.json()['avatar_url'])
            with My_mysql(db='md2') as c:
                c.execute(sql)
            # 查出来数据进行赋值
            with My_mysql(db='md2') as c:
                c.execute("select * from user where username='%s'" % name)
                user_ret = mytool.dictfetch(c)[0]
            gitee_id = user_ret['username']
            user_id = user_ret['id']
            user_type = user_ret['type']

        return redirect("http://localhost:8080?another_id=" + str(gitee_id) + "&uid=" + str(user_id)+"&type="+str(user_type))

    def __str__(self):
        return 'https://gitee.com/oauth/authorize?client_id=0a703af338f10cb37bee6a14d0fdb0f1faf4d693ff19c216900e0613210131a5&redirect_uri=http://127.0.0.1:5000/gitee&response_type=code'
user.add_url_rule('/gitee', view_func=Gitee_Login.as_view('gitee'))

class Weibo_Login(views.View):
    methods = ['GET']
    def dispatch_request(self):
        code = request.args.get('code', None)
        # 微博接口地址
        access_token_url = "https://api.weibo.com/oauth2/access_token"
        # 定义参数
        re = requests.post(access_token_url, data={
            "client_id": '568557081',
            "client_secret": "759b7ef576d8320cfdb12440767d03d8",
            "grant_type": "authorization_code",
            "code": code,
            "redirect_uri": "http://127.0.0.1:5000/weibo",
        })
        # 获取用户信息
        res = requests.get('https://api.weibo.com/2/users/show.json',
                           params={"access_token": re.json()["access_token"], "uid": re.json()["uid"]})
        username = str(res.json()['name'])
        print(username)
        # 判断是否用新浪微博登录过
        with My_mysql(db='md2') as c:
            c.execute("select * from user where username='%s'" % username)
            user_ret = mytool.dictfetch(c)[0]
        if user_ret:
            # 代表曾经登录过
            sina_id = user_ret['username']
            user_id = user_ret['id']
            user_type = user_ret['type']
        else:
            # 首次登陆 写入数据库
            sql="INSERT INTO USER VALUES (NULL,NULL,'%s','%s',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL)"%(username,mytool.md5_str(res.json()['id']))
            with My_mysql(db='md2') as c:
                c.execute(sql)
            # 查出来数据进行赋值
            with My_mysql(db='md2') as c:
                c.execute("select * from user where username='%s'" % username)
                user_ret = mytool.dictfetch(c)[0]
            sina_id = user_ret['username']
            user_id = user_ret['id']
            user_type = user_ret['type']
        return redirect("http://localhost:8080?another_id=" + str(sina_id) + "&uid=" + str(user_id) + "&type=" + str(user_type))

    def __str__(self):
        return 'https://api.weibo.com/oauth2/authorize?client_id=568557081&redirect_uri=http://127.0.0.1:5000/weibo'

user.add_url_rule('/weibo', view_func=Weibo_Login.as_view('weibo'))

class Ding_Login(views.View):
    methods = ['GET']
    def dispatch_request(self):
        import hmac
        import urllib
        import base64
        from hashlib import sha256
        code = request.args.get('code', None)
        t = time.time()
        # 时间戳/毫秒
        timestamp = str((int(round(t * 1000))))
        appSecret = "sqk5DOVyuunK4SCtKTWLli7PyGgn0Bq_vkKb50fdihwerCwauDE5_7d0YuHRoa3n"
        # 构造签名
        signature = base64.b64encode(
            hmac.new(appSecret.encode('utf-8'), timestamp.encode('utf-8'), digestmod=sha256).digest())
        data = {'tmp_auth_code': code}
        headers = {'Content-Type': 'application/json'}
        res = requests.post('https://oapi.dingtalk.com/sns/getuserinfo_bycode?signature=' + urllib.parse.quote(
            signature.decode("utf-8")) + "&timestamp=" + timestamp + "&accessKey=dingoaapwef2py4eov6nwh",
                            data=json.dumps(data), headers=headers)

        username = res.json()['user_info']['nick']
        # 判读是否是第一次
        with My_mysql(db='md2') as c:
            c.execute("select * from user where username='%s'" % username)
            user_ret = mytool.dictfetch(c)[0]

        if user_ret:
            # 代表曾经登录过
            ding_id = user_ret['username']
            user_id = user_ret['id']
            user_type = user_ret['type']
        else:
            # 首次登陆 写入数据库
            sql="INSERT INTO USER VALUES (NULL,NULL,'%s','%s',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL)"%(username,mytool.md5_str(res.json()['user_info']['openid']))
            with My_mysql(db='md2') as c:
                c.execute(sql)

            # 查出来数据进行赋值
            with My_mysql(db='md2') as c:
                c.execute("select * from user where username='%s'" % username)
                user_ret = mytool.dictfetch(c)[0]
            ding_id = user_ret['username']
            user_id = user_ret['id']
            user_type = user_ret['type']

        return redirect( "http://localhost:8080?another_id=" + str(ding_id) + "&uid=" + str(user_id) + "&type=" + str(user_type))

    def __str__(self):
        return 'https://oapi.dingtalk.com/connect/qrconnect?appid=dingoaapwef2py4eov6nwh&response_type=code&scope=snsapi_login&state=STATE&redirect_uri=http://127.0.0.1:5000/dingtalk'
user.add_url_rule('/dingtalk', view_func=Ding_Login.as_view('ding'))

@user.route("/user")  # 这里添加路由和视图函数的时候与在Flask对象中添加是一样的
def show_user():
    return "这里是用户模块"

# 工厂类
class User_factory:
    @staticmethod
    def create_user(name):
        if name=='gitee':
            return Gitee_Login()
        elif name =='sina':
            return Weibo_Login()
        elif name =='ding':
            return Ding_Login()

@user.route('/another_user/',methods=['GET','POST'])
def another_login():
    # 获取登录方式
    method=request.args.get('method')
    # 接受指定创建对象
    userf=User_factory.create_user(method)
    # 获取对象的说明 是第三方登录页面的url
    return redirect(userf.__str__())

@user.route('/user/',methods=['GET','POST'])
def Login_User():
    if request.method=='GET':
        jwt= request.args.get('jwt')
        # 验证jwt是否符合
        ret=mytool.decode_jwt_str(jwt)
        # 查出redis中的数据
        res = r.hgetall(jwt)
        if ret and res:
            user_dict={}
            for k,v in res.items():
                user_dict[k.decode('utf-8')]=v.decode('utf-8')
            return jsonify({'code': 200, 'msg': 'ok','user_data':user_dict})
        else:
            return jsonify({'code': 403, 'msg': 'jwt失效'})

    if request.method =='POST':
        username=request.form.get('username')
        password=request.form.get('password')
        try:
            sql = "select * from user where username='%s' and password='%s'" % (username, mytool.md5_str(password))
            with My_mysql(db='md2') as c:
                c.execute(sql)
                res=mytool.dictfetch(c)[0]
                print(res)
            if res:
                my_dict = {'uid': res['id'], 'rid':res['rid'],'username':res['username'],'type':res['type'],}
                jwt_str = mytool.encode_jwt_str(my_dict)
                # 存入redis 并设置过期时间
                r.hmset(jwt_str,my_dict)
                r.expire(jwt_str,14400)
                return jsonify({"code": 200,'msg':'登录成功','username':res['username'],'uid':res['id'],'type':res['type'],'jwt':jwt_str})
            else:
                return jsonify({"code": 403,'msg':'用户名或密码错误'})
        except Exception as e:
            print(e)

@user.route('/send_mail/', methods=['POST'])
def send_email():
    email = request.form.get('email')
    # 计算生成验证码
    Captcha = random.randint(1000, 9999)
    if email:
        contents = '尊敬的用户您好：您正在注册使用xx教育网站 验证码为：%s 有效时间为两分钟'%Captcha
        try:
            mytool.Send_Mail('注册邮箱验证',contents,email)
            r.set(email, Captcha, ex=120)
            return jsonify({'code': 200, 'Captcha': Captcha, 'msg': '发送成功'})
        except Exception as e:
            print(e)
            return jsonify({'code': 403,'msg': '发送失败'})


@user.route('/register/',methods=['POST'])
def Register_user():
    if request.method=='POST':
        code = request.form.get('code')
        email = request.form.get('email')
        username = request.form.get('username')
        # 获取验证码
        Captcha = str(r.get(email), encoding='utf-8')
        # 如果验证码不正确
        if Captcha is None or code != Captcha:
            return jsonify({'code': 403, 'msg': '验证码无效'})

        # 判断是否存在
        with My_mysql(db='md2') as c:
            c.execute("select * from user where username='%s'" % username)
            user_ret = mytool.dictfetch(c)[0]

        if user_ret:
            return jsonify({'code': 403, 'msg': '已有该用户'})
        try:
            # 写入数据库
            sql="INSERT INTO USER VALUES (NULL,NULL,'%s','%s',NULL,'%s',NULL,NULL,'%s',NULL,NULL,NULL)"\
                %(username,mytool.md5_str(request.form.get('password')),request.form.get('phone'),request.form.get('email'),)
            with My_mysql(db='md2') as c:
                c.execute(sql)
            return jsonify({'code': 200, 'msg': '注册成功'})
        except Exception as e:
            print(e)
            return jsonify({'code': 403, 'msg': '注册失败'})


